#include "http_server.h"
#include "../../log.h"
#include <boost/beast/core/ostream.hpp>
#include <boost/beast/http/read.hpp>
#include <memory>

uint32_t HttpConnection::RequestCount()
{
    static uint32_t count = 0;
    return ++count;
}

std::time_t HttpConnection::ConnectTime()
{
    return std::time(nullptr);
}

HttpConnection::HttpConnection(TCP::socket socket)
:m_socket(std::move(socket))
,m_request(std::make_shared<boost::beast::http::request<boost::beast::http::dynamic_body>>())
,m_response(std::make_shared<boost::beast::http::response<boost::beast::http::dynamic_body>>())
,m_dispatch(std::make_shared<ServletDispatch>())
{
}

void HttpConnection::Start()
{
    _ReadRequest();
    _CheckTimeout();
}

void HttpConnection::HttpAccept(TCP::acceptor& accept, TCP::socket& socket)
{
    accept.async_accept(socket,[&](boost::system::error_code ec){
        if(!ec)
        {
            HttpConnection::ptr connect(std::make_shared<HttpConnection>(std::move(socket)));
            connect->Start();
        }
        HttpAccept(accept, socket);
    });
}

void HttpConnection::_CheckTimeout()
{
    auto self = shared_from_this();
    m_timer.async_wait([self](boost::system::error_code ec){
        if(!ec)
        {
            self->m_socket.close(ec);
        }
    });
}

void HttpConnection::_ReadRequest()
{
    auto self = shared_from_this();
    boost::beast::http::async_read(m_socket, m_buffer, *m_request,
     [self](boost::system::error_code ec, std::size_t bytes){
        boost::ignore_unused(bytes); //忽略没有使用的参数
        if(ec)
        {
            log_error("read error, code:{}, meg:{}", ec.value(), ec.message());
            self->m_socket.close(ec);
            return;
        }

        self->_ProcessRequest();
    });
}

void HttpConnection::_ProcessRequest()
{
    m_response->version(m_request->version());
    m_response->keep_alive(false);

    switch (m_request->method()) //判断请求类型
    {
    case Verb::get:
        m_response->result(Status::ok); //设置返回状态码
        m_response->set(Field::server, "Lightning-server");
        CreateResponse();
        _WriteResponse();
        break;
    case Verb::post:
        m_response->result(Status::ok); //设置返回状态码
        m_response->set(Field::server, "Lightning-server");
        //这里要解析body中的数据
        CreateResponse();
        _WriteResponse();
        break;
    default:
        m_response->result(Status::bad_request);
        //设置已文本方式回复
        m_response->set(Field::content_type, "text/plain"); 
        //设置消息体
        boost::beast::ostream(m_response->body()) << "Invalid request-method '"
            << std::string(m_request->method_string()) << "'";
        log_warning("bad request, ip:{}", m_socket.remote_endpoint().address().to_string());
        break;
    }
}

void HttpConnection::CreateResponse()
{
    std::string path = m_request->target();
    auto servlet = m_dispatch->getMatchedServlet(path);
    servlet->handle(m_request, m_response);

}

void HttpConnection::_WriteResponse()
{
    auto self = shared_from_this();
    m_response->content_length(m_response->body().size());
    boost::beast::http::async_write(m_socket, *m_response, 
    [self](boost::system::error_code ec, std::size_t bytes){
        self->m_socket.shutdown(TCP::socket::shutdown_send);
        self->m_timer.cancel();
    });
}